<!DOCTYPE html>
<html>
<head>
  <title>HTML5 Geo-location test</title>
  <script type="text/javascript" src="../test_bootstrap.js"></script>
  <script type="text/javascript">
    goog.require('bot');
    goog.require('bot.geolocation');
    goog.require('bot.html5');
    goog.require('bot.test');
    goog.require('bot.userAgent');
    goog.require('goog.Promise');
    goog.require('goog.labs.userAgent.platform');
    goog.require('goog.testing.TestCase');
    goog.require('goog.testing.jsunit');
    goog.require('goog.userAgent');
    goog.require('goog.userAgent.product');
  </script>

  <script type="text/javascript">
    // WebDriver does not enable geolocation for Android.
    // WebDriver does not enable geolocation for Edge.
    // WebDriver does not enable geolocation for Firefox.
    // WebDriver does not enable geolocation for IE 9.
    // WebDriver does not enable geolocation for Safari.
    // Chrome 50+ disables geolocation APIs on insecure origins; see
    // https://goo.gl/rStTGz.
    var GEOLOCATION_NOT_WORKING =
        !bot.html5.isSupported(bot.html5.API.GEOLOCATION) ||
        goog.userAgent.product.ANDROID ||
        goog.userAgent.product.EDGE ||
        goog.userAgent.product.FIREFOX ||
        goog.userAgent.product.SAFARI ||
        goog.userAgent.product.CHROME ||
        // Geolocation is blocked by user consent screen on Chrome for Android.
        (goog.labs.userAgent.platform.isAndroid() &&
            goog.userAgent.product.CHROME) ||
        bot.userAgent.IE_DOC_9;


    function setUpPage() {
      goog.testing.TestCase.getActiveTestCase().promiseTimeout = 10000; // 10s
    }

    /**
     * This method checks if the device location
     * can be retrieved, i.e. non-null value of Position within the timeout
     * period.
     */
    function testLocationWithinDefaultInterval() {
      if (GEOLOCATION_NOT_WORKING) {
        return;
      }
      return new goog.Promise(function(success, fail) {
        try {
          bot.geolocation.getCurrentPosition(success, function(error) {
            switch (error.code) {
              case error.POSITION_UNAVAILABLE:
                // Some test machines run on a private ip address range where
                // location is not be available, so do not consider this case
                // as an error.
                success();
                return;
              case error.PERMISSION_DENIED:
                fail('User denied the request for Geolocation.');
                return;
              case error.TIMEOUT:
                fail('When enabled, location should be known within ' +
                    (bot.geolocation.DEFAULT_OPTIONS.timeout / 1000) + 's');
                return;
              default:
                fail('An unknown error occurred. ' + error.message);
                return;
            }
          });
        } catch (e) {
          assertEquals(e.code, bot.ErrorCode.UNKNOWN_ERROR);
        }
      });
    }

    /**
     * Tested with Chrome and Firefox. It checks if the device location cannot
     * can be retrieved, i.e. null value of Position, when requested to
     * retrieve the position with high accuracy and immediately (no cached).
     * Note: Firefox seems to return the position even in this case.
     * The HTML5 standard states If the value of the timeout variable is 0,
     * invoke the errorCallback (if present) with a new PositionError object
     * whose code attribute is set to TIMEOUT.
     */
    function testLocationNoTimeout() {
      if (GEOLOCATION_NOT_WORKING) {
        return;
      }

      var posOptions = {
        enableHighAccuracy: true,
        maximumAge: 0,
        timeout: 0
      };

      return new goog.Promise(function(success, fail) {
        try {
          bot.geolocation.getCurrentPosition(
            goog.partial(fail,
                'Location within 0s timeout interval and 0s max age fails'),
            success,
            posOptions);
        } catch (e) {
          assertEquals(e.code, bot.ErrorCode.UNKNOWN_ERROR);
          success();
        }
      });
    }

    // TODO: Add more tests to check the returned value.
  </script>
</head>
<body>
</body>
</html>
